﻿using AntdUI;
using Mapster;
using Serilog;
using SocketCore.Client;
using SocketCore.Common.Config;
using SocketCore.Common.Event;
using SocketCore.Common.Message;
using System.ComponentModel;
using System.Net;
using WorkTool2.Classes.Data;
using WorkTool2.Controls;
using WorkTool2.Entities;
using WorkTool2.Helpers;

namespace WorkTool2
{
    public partial class Main : Window
    {
        private ClientManager _clientManager;

        private ClientConfig _clientConfig;

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public float UpdateProgressValue
        {
            get { return progress_update.Value; }
            set { progress_update.Value = value; }
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string UpdateLableText
        {
            get { return label_update.Text; }
            set { label_update.Text = value; }
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public void UpdateVisibleShow()
        {
            panel_update.Visible = true;
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public void UpdateVisibleHide()
        {
            panel_update.Visible = false;
        }

        public Main()
        {
            InitializeComponent();
            windowBar.Text += " " + $"[{Application.ProductVersion}]";
            Load += Main_Load;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            ITask.Run(() =>
            {
                setting_dropdown.Items.Add(new SelectItem("配置文件").SetIcon("SettingOutlined"));
                menu.Items.Add(new MenuItem("Git分支比较", "").SetTag(1));
                menu.Items.Add(new MenuItem("工作月报表", "").SetTag(2));
                menu.Items.Add(new MenuItem("假期查询&津贴生成", "").SetTag(3));
                menu.Items.Add(new MenuItem("Base64&文件互转", "").SetTag(4));
                menu.Items.Add(new MenuItem("合并PDF文档", "").SetTag(5));
                menu.Items.Add(new MenuItem("数据库管理", "").SetTag(6));
                menu.Items.Add(new MenuItem("Markdown", "").SetTag(7));
                OpenPage(9999, "");
            });
        }

        private async void Main_Load(object? sender, EventArgs e)
        {
            _clientConfig = new ClientConfig
            {
                MaxReconnectAttempts = null,
                IPAddress = Dns.GetHostAddresses("SZO-23-P03").First(x => !x.IsIPv6LinkLocal),
                Version = Application.ProductVersion
            };
            _clientConfig.EventHub.OnEvent += async (sender, e) =>
            {
                switch (e.Type)
                {
                    case SocketEventType.Log:
                        //var logMessage = e.GetData<SocketLogMessage>();
                        //Log.Error($"[Log][{e.DateTime:yyyy-MM-dd HH:mm:ss}] {logMessage.Message}");
                        break;

                    case SocketEventType.Connect:
                        //var connectMessage = e.GetData<SocketClientConnect>();
                        //Log.Error($"[Connect][{e.DateTime:yyyy-MM-dd HH:mm:ss}] {connectMessage.ClientInfo}:{connectMessage.IsConnect}");
                        break;

                    case SocketEventType.MessageReceived:
                        var receivedMessage = e.GetData<SocketClientMessage>();
                        var messageData = receivedMessage.Message.Deserialize<MessageData<object>>();
                        switch (messageData.MessageDataType)
                        {
                            case MessageDataType.ForcedUpdate:
                                var forcedUpdate = receivedMessage.Message.Deserialize<MessageData<UpdateMessage>>();
                                await UpdateHelper.ManagerStartUpdater(this, forcedUpdate.Data.Adapt<VersionInfo>(), true);
                                break;

                            case MessageDataType.BetaUpdate:
                                var betaUpdate = receivedMessage.Message.Deserialize<MessageData<UpdateMessage>>();
                                var versionInfo = betaUpdate.Data.Adapt<VersionInfo>();
                                if (AntdUI.Modal.open(new Modal.Config(this, "更新提示", $"邀请您参与[{versionInfo.Version}]版本的内测更新！是否立即更新？{(string.IsNullOrEmpty(versionInfo.Description) ? "" : $"\n本次更新内容：\n{versionInfo.Description}")}", TType.Info)
                                {
                                    CancelText = "否",
                                    OkText = "是"
                                }) == DialogResult.OK)
                                {
                                    await UpdateHelper.ManagerStartUpdater(this, versionInfo);
                                }
                                break;

                            case MessageDataType.Notification:
                                Notification.success(this, $"来自{receivedMessage.ClientInfo}的消息通知", messageData.Data.ToString(), TAlignFrom.BR);
                                break;

                            case MessageDataType.Dialog:
                                AntdUI.Modal.open(new Modal.Config(this, $"来自{receivedMessage.ClientInfo}的消息通知", messageData.Data.ToString(), TType.Warn)
                                {
                                    Mask = true,
                                    MaskClosable = false,
                                    Keyboard = false,
                                    CancelText = null,
                                    OkText = "好的",
                                });
                                break;

                            default:
                                break;
                        }
                        break;

                    case SocketEventType.Heartbeat:
                        var heartbeatMessage = e.GetData<SocketHeartbeatMessage>();
                        Log.Error($"[Heartbeat][{e.DateTime:yyyy-MM-dd HH:mm:ss}] {heartbeatMessage.Message}");
                        break;
                }
            };
            _clientManager = new ClientManager(_clientConfig);
            try
            {
                await _clientManager.ConnectAsync();
            }
            catch (Exception ex)
            {
                Log.Error($"[CLIENT] Error: {ex.Message}");
            }
            finally
            {
            }
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            _clientManager.Disconnect();

            base.OnFormClosed(e);
        }

        private void menu_SelectChanged(object sender, MenuSelectEventArgs e)
        {
            setting_dropdown.SelectedValue = -1;
            OpenPage((int)e.Value.Tag, e.Value.Text.ToString());
        }

        private void menu_ItemClick(object sender, MenuItemEventArgs e)
        {
            e.Item.Select = false;
            if (e.Item.Tag.ToString() == "7")
            {
                var markdown = new MarkdownForm();
                markdown.Show();
            }
        }

        public Control? control_add;

        private void OpenPage(int id, string description)
        {
            control_add = id switch
            {
                1 => new Controls.CherryPick(this),
                2 => new Controls.WorkMonthlyReport(this),
                3 => new Controls.HolidayStatistics(this),
                4 => new Controls.Base64AndFileConversion(this),
                5 => new Controls.PDFMerge(this),
                6 => new Controls.DataBaseQuery(this),
                9000 => new Controls.AppSettings(this),
                9999 => new Controls.Calendar(this),
                _ => null,
            };
            if (control_add != null)
            {
                if (id != 9000)
                    CloseFloatButton();
                windowBar.SubText = description;
                if (windowBar.Tag is Control control)
                {
                    control.Dispose();
                    Controls.Remove(control);
                }
                windowBar.Tag = control_add;
                BeginInvoke(new Action(() =>
                {
                    virtualPanel.Visible = false;
                    control_add.Dock = DockStyle.Fill;
                    Win32.WindowTheme(control_add);
                    AutoDpi(control_add);
                    Controls.Add(control_add);
                    control_add.BringToFront();
                    control_add.Focus();
                    windowBar.ShowBack = id != 9999;
                }));
            }
        }

        private void windowBar_BackClick(object sender, EventArgs e)
        {
            BeginInvoke(new Action(() =>
            {
                //if (windowBar.Tag is Control control)
                //{
                //    control.Dispose();
                //    Controls.Remove(control);
                //}
                //windowBar.ShowBack = false;
                //virtualPanel.Visible = true;
                CloseFloatButton();
                virtualPanel.Focus();
                menu.USelect();
                OpenPage(9999, "");
            }));
        }

        private async void update_btn_Click(object sender, EventArgs e)
        {
            await UpdateHelper.Update(this);
        }

        private void setting_dropdown_ItemClick(object sender, ObjectNEventArgs e)
        {
            menu.USelect();
            switch (e.Value.ToString())
            {
                case "配置文件":
                    OpenFloatButton();
                    OpenPage(9000, e.Value.ToString());
                    break;

                default:
                    break;
            }
            setting_dropdown.SelectedValue = -1;
        }

        #region 悬浮按钮

        private AntdUI.FormFloatButton FloatButton = null;

        private void OpenFloatButton()
        {
            if (FloatButton == null)
            {
                FloatButton = AntdUI.FloatButton.open(new FloatButton.Config(this, [
                    new AntdUI.FloatButton.ConfigBtn("save").SetIcon("SaveOutlined").SetTooltip("保存"),
                    new AntdUI.FloatButton.ConfigBtn("rollback").SetIcon("RollbackOutlined").SetTooltip("撤销"),
                    new AntdUI.FloatButton.ConfigBtn("reset").SetIcon("ReloadOutlined").SetTooltip("重置"),
                ], btn =>
                {
                    switch (btn.Name)
                    {
                        case "save":
                            ((AppSettings)control_add).Save();
                            break;

                        case "rollback":
                            ((AppSettings)control_add).Rollback();
                            break;

                        case "reset":
                            ((AppSettings)control_add).Reset();
                            break;

                        default:
                            break;
                    }
                }));
                FloatButton.config.Btns[0].Type = AntdUI.TTypeMini.Primary;
            }
            else
            {
                if (control_add is not AppSettings)
                {
                    CloseFloatButton();
                }
            }
        }

        private void CloseFloatButton()
        {
            if (FloatButton != null)
            {
                FloatButton.Close();
                FloatButton = null;
            }
        }

        #endregion

        private void btn_mode_Click(object sender, EventArgs e)
        {
            //if (setcolor)
            //{
            //    var color = AntdUI.Style.Db.Primary;
            //    AntdUI.Config.IsDark = !AntdUI.Config.IsDark;
            //    Dark = AntdUI.Config.IsDark;
            //    AntdUI.Style.SetPrimary(color);
            //}
            //else
            //{
            Config.IsDark = !Config.IsDark;
            Dark = Config.IsDark;
            //}

            btn_mode.Toggle = Dark;
            if (Dark)
            {
                windowBar.BackColor = Color.Black;
                windowBar.ForeColor = Color.White;
                BackColor = Color.Black;
                ForeColor = Color.White;
            }
            else
            {
                windowBar.BackColor = Color.White;
                windowBar.ForeColor = Color.Black;
                BackColor = Color.White;
                ForeColor = Color.Black;
            }
            OnSizeChanged(e);
        }

        private void history_btn_Click(object sender, EventArgs e)
        {
            Drawer.open(this, new History(this)
            {
                Size = new Size(700, 600),
            }, TAlignMini.Right);
        }

        public async Task AddHistoryData(List<HistoryData> list)
        {
            try
            {
                var entities = list.Adapt<List<HistoryEntity>>();
                await SqlSugarHelper.SqliteDb.Insertable(entities).ExecuteCommandAsync();
            }
            catch (Exception ex)
            {
                Log.Error(ex, ex.Message);
            }
        }

        public async Task AddHistoryData(HistoryData data)
        {
            await AddHistoryData([data]);
        }

        public async Task UpdateHistoryData(int id, bool exists)
        {
            var entity = await SqlSugarHelper.SqliteDb.Queryable<HistoryEntity>().InSingleAsync(id);
            if (entity != null)
            {
                entity.Exists = exists;
                await SqlSugarHelper.SqliteDb.Updateable(entity).ExecuteCommandAsync();
            }
        }
    }
}